#include "PreCompile.hpp"
#include "ContentModule.hpp"
#include "InputFilesSet.hpp"
#include "InputFiles.hpp"
#include "Project.hpp"
#include "ErrorListener.hpp"

namespace BuildNG
{
  static const char CONTENT_MODULE_XML_NAME[] = "content";

  void ContentModule::init()
  {
    ModuleTypeInfo type_info;
    type_info.create_func = ModuleTypeInfo::ctor_wrapper<ContentModule>;
    register_module_type(CONTENT_MODULE_XML_NAME,type_info);
  }

  void ContentModule::shutdown()
  {
  }

  ContentModule::ContentModule()
  {
    input_files = Glib::RefPtr<InputFilesSet>(new InputFilesSet);
  }
  
  ContentModule::~ContentModule()
  {
  }
  
  void ContentModule::load_from_xml(const Xml::Element &xml)
  {
    input_files->clear();

    set_name(xml.get_attribute_value("name"));

    Xml::Attribute *dest_root_attr = xml.try_get_attribute("dest-path-root");
    if(dest_root_attr)
    {
      if(dest_root_attr->get_value() == "executable-dir")
        dest_root = OutputDirType_ExecutableDir;
      else if(dest_root_attr->get_value() == "data-dir")
        dest_root = OutputDirType_DataDir;
      else if(dest_root_attr->get_value() == "user-config-dir")
        dest_root = OutputDirType_UserConfigDir;
      else
      {
        throw Xml::ContentException(*dest_root_attr,"Invalid value for the \"dest-path-root\" attribute: \"" + dest_root_attr->get_value() + "\".");
      }
    }
    else
    {
      dest_root = OutputDirType_DataDir;
    }

    input_files->add_group_from_xml(xml);
  }
  
  void ContentModule::save_to_xml(Xml::Element &xml) const
  {
    assert(!"not implemented yet");
  }

  bool ContentModule::build(BuildContext &context,Glib::RefPtr<ErrorListener> error_listener)
  {
    std::vector<Glib::ustring> files = input_files->build_physical_files(context);

    bool success = true;
    for(int j = 0;j < input_files->get_num_input_files_entries();j++)
    {
      Glib::RefPtr<InputFiles> cur_input_files = input_files->get_input_files_entry(j);
      for(int i = 0;i < (int)files.size();i++)
      {
        try
        {
          context.copy_to_output_dir(Glib::build_filename(
            get_module_dir(),files[i]),files[i],dest_root);
        }
        catch(const std::exception &err)
        {
          ErrorLocationInfo loc_info;
          bool has_loc_info = cur_input_files->get_xml_element_location_info(loc_info);
          if(!has_loc_info)
            loc_info.set_not_specified();
          
          error_listener->report_error(loc_info,err.what());

          success = false;
        }
      }
    }

    return success;
  }
}
